package com.qf.aop;

import com.qf.entity.R;
import com.qf.entity.User;
import com.qf.util.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
public class LoginAop {

    /**
     * 环绕增强 - 判断当前是否已经登录
     * @return
     */
    @Around("@annotation(IsLogin)")
    public Object loginHandler(ProceedingJoinPoint joinPoint){

        //1、获得客户端传递过来的请求对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        //2、通过请求request获得token参数
        String token = request.getParameter("token");
        String devid = request.getParameter("devid");

        //3、判断是否已经登录
        User user = JwtUtil.getUserByToken(token, devid);
        if (user == null) {
            //4、当前未登录，判断是否需要强制登录
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            IsLogin isLogin = method.getAnnotation(IsLogin.class);

            //5、判断是否需要强制登录
            if (isLogin.mustLogin()) {
                //需要强制登录，跳转到登录页面
                return new R().setCode(R.CODE.MUST_LOGIN);
            }
        }

        //6、无需登录也可以访问接口或者已经登录了 - user
//        Object[] args = joinPoint.getArgs();
//        args[args.length - 1] = user;

        UserUtil.setUser(user);

        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            //移除当前用户的保存对象 - 避免线程池的混乱
            UserUtil.remove();
        }

        return result;

    }
}
